Package by Feature
PBF
Package by Feature
とあるディレクトリ構造
機能ごとにディレクトリをわける
Layered Architectureをlayerで区切るのではなく、機能ごとに区切る
https://gyazo.com/cce5e47cdccd054932843be7f3a987ef
同じ色を同じディレクトリに入れる感じ
PBFを実践して得られる嬉しさにはいくつかの種類があるようにも思うmrsekut.icon
単純にdirectoryを分けるだけでも、人間の認知のしやすさが向上する
どこに何があるのかがわかる
探す手間が減り、新規のものをどこに置けばよいかに迷わない
一覧性が上がる
関連の低いものとの依存を如何に減らすか
「packageの中で、他のpackageとやり取りして良いもの」のルールを定めることで、依存を格段に減らすことができる
そうすることで、
directoryを消した時の影響範囲の小ささや、
他のproductへの移行の容易さが向上する
最悪、pacakgeの中がカオスになっても良い
カオスをpackageの中で閉じ込めれば、外には影響しない
これはlinterなどを使って機械的にルールの遵守を強制できる
これはPBLだとほぼ不可能
Packageに閉じてれば何をやっても良い
directoryを見るだけで、機能の一覧を知ることができる
directoryを開けば、それは機能一覧を意味する
Screaming Architecture
1機能を削りたい、と思った時にdirectoryを削除するだけで済む
機能を追加しやすい
機能まるごとの移動もしやすい
後に階層がネストしたとしても、directoryを丸ごと移動させるだけで済む
code:before
Login
Post
code:after
Auth
Login // ネストが深まったが、ディレクトリを移動するだけで済む
Register
Post
機能ごとのlibraryに切り分けやすい
凝集度が上がる
このディレクトリ構造にすることで、packageを超えて依存させないという意識を作ることができる ref
package間の結合度が下がる
異なるpackageとの依存が薄くなる
別々で並行で開発できる
カオスをpackageに閉じ込められる
directory構造だけなら、階層をガン無視してimportすることはできてしまうmrsekut.icon
公開するものを限定して、これができないようにしないといけない
これはlinterなり、何なりを使って補助して貰う必要がある
関連
Package by Component
Folder by Feature
参考
Package by Feature
/mrsekut-book-4048930656/282 (第34章 書き残したこと)
PBFではなく、Package by Componentの解説が書いている
#WIP
feature同士の結合度みたいな数値出せそう
すうしきかんがえて
AとBという2つのfeatureを独立に作っているつもりだったが、
AではBを割とimportしてるし、
BではAを割とimportしてる
みたいな状況を可視化する感じ
https://speakerdeck.com/okunokentaro/frontend-conference-2019?slide=33
プロダクト全体で共有する機能はshared/とかcommon/のようなdirに入れる ref
再利用性が上がる
ただし、最初から抽象化しない
できるだけ、固有のdomainの中に置いて、他からも使うようになったらcommon/に移す
Rule Of Three
mrsekut.iconが気にしているのは、構造はfeatureを跨ぐということか
その場合に、
その構造は共通して使うべきか?
共通して使うならどこに置くべきか?
という問題が出てくる
これはfrontend特有の話だと思うmrsekut.icon
View Componentが固有のEntityに依存しないことも多い、ということに似ている
packageに2種類あるきがしている
構造を提供するpackageと、
featureを提供するpackage
の2種類があるんじゃないだろうか?
ディレクトリとファイルレベルのLCOMをやると言っても限界がありそう
commonのようなものを用意すると、それの依存関係はファイルツリーを見るだけじゃわからない
でも、それはそもそもPBFの目的でもなさそう
「依存関係をファイルツリーに落とし込む」ことはそもそも目指してない
し、今のネスト構造ならそもそも無理だろう
また、迷った時の指針として
とりあえず小さく作る
とりあえず大きく作る
のどちらが後から修正しやすいかも考えたい
http://www.javapractices.com/topic/TopicAction.do?Id=205
tweet
https://twitter.com/sawat1203/status/897330171404890113
引用も色々
https://labs.gree.jp/blog/2013/12/9354/
/miyamonz/機能を構成に依存させない
/miyamonz-projects/機能でフォルダを分けるのはOOUIっぽい
PBF(Package by Feature), no more PBL(Package by Layer) | by Avijit Karmakar | MindOrks | Medium
/miyamonz/package by feature
https://labs.gree.jp/blog/2013/12/9354/
https://www.techyourchance.com/popular-package-structures/
https://labs.gree.jp/blog/2013/12/9354/
https://phauer.com/2020/package-by-feature/
https://stackoverflow.com/questions/11733267/is-package-by-feature-approach-good
https://github.com/yukitos/notes/blob/master/A_recipe_for_a_functional_app/Organizing%20modules%20in%20a%20project.md#%E3%83%AC%E3%82%A4%E3%83%A4%E3%83%BC%E8%A8%AD%E8%A8%88%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E9%96%A2%E6%95%B0%E7%9A%84%E3%82%A2%E3%83%97%E3%83%AD%E3%83%BC%E3%83%81
https://twitter.com/simonbrown/status/969108890527903744
https://dzone.com/articles/package-by-layer-for-spring-projects-is-obsolete
1つのFeatureとはなにか
layerとディレクトリ構造
そもそもやりたいことは、
修正のコストを抑えたい
追加のコストを抑えたい
そのために、依存する数や方向をコントロールすればいい
全体を見た時に、修正が頻繁に起こるものと、そうでないものに分けて、依存の向きを決定することで、修正箇所が一気に減る
依存する際に、循環参照があると、修正のコストが上がる
こういった依存の向きは、自分ひとりでわかっていればいいものではなく、チーム間で共有されていないと意味がない
この共有をわかりやすく行うために、ディレクトリを分けたり、ファイルを分けたりする
ディレクトリ構造は、人間の認識氏やすさだけのもの?
近くにあるものは、関係のあるもの、と捉えることができる
一覧で見やすい
機能を移す時、機能を削除する時に、探す手間が減る
でも、これは言う手もそこまでメリットとして大きくない気もする
アルニコしたことはないけど
なくても探すことはできるわけで
認知以上の嬉しさもある
linterなどで、package外のやり取りを禁止しやすい
pathを見るだけでルール化できる
ディレクトリ構造がマジで見た目だけの話なのであれば、import文とかどうでもいいんだよな
Scrapboxみたいに、全ファイルを兄弟として扱った上で、
人や、見る状況に応じて、ディレクトリのツリー構造を返るだけすれば良い
import文がツリー構造になっているのがおかしい
名前のコンフリクトとかは起きそうだけど
idにすればいい
1つのpackageに何を入れるか?で迷う問題は、結局PBFで何を解決するか?に着目しないといけない
そのためには、そもそもlayerが何のためにあるか、とか
Componentの設計方針とかを理解しないといけない
その前にいったん用語の整理をしておきたい #??
moduleとは
#??
Componentとは
CAではデプロイの単位
packageとは
#??
componentとpackageの違いとは?
PBFとPBCが別概念であるなら、そこで触れられているかも
featureとは
今のイメージとしては、
moduleがだいたい1ファイル
packageはmoduleのまとまり
componentはよくわからん
デプロイの単位なのであれば、packageやmoduleの上下の概念ではないかもしれない
1moduleが1componentのこともあれば、複数packageで1compnentのこともある?
RepositoryはAPIベースで切るのか、ドメインベースで切るのか
1つのAPIのレスポンスが複数のEntityにまたがるようなものだった場合どうするのか
それはAPIの設計が悪い、ということになるのか?
Repositoryから、他のRepositoryを呼んでも良いのか?